package com.example.mqttclient;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import com.example.mqttclient.mqtt.MqttService;
import com.example.mqttclient.protocol.AirConditioningMessage;
import com.example.mqttclient.protocol.BoolMessage;
import com.example.mqttclient.protocol.FloatMessage;
import com.example.mqttclient.protocol.IntMessage;
import com.example.mqttclient.protocol.PumpMessage;
import com.example.mqttclient.protocol.SocketMessage;
import com.google.gson.Gson;
import org.eclipse.paho.client.mqttv3.MqttException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DevicesDemoActivity extends AppCompatActivity implements MqttService.MqttEventCallback, CompoundButton.OnCheckedChangeListener {
    private TextView connectState, temperatureValue, humidityValue, pmValue, gasValue, doorStatus;
    private EditText airConditioningValue;
    private MqttService.MqttBinder mqttBinder;
    private String TAG = "MainActivity";
    private Switch parlourLightSwitch, curtainSwitch, fanSocketSwitch, airConditioningSwitch;
    private Map<String, Integer> subscribeTopics = new HashMap<>();
    private static final int GAS_ALARM_THRESHOLD = 70; // 假设阈值为 70
    private LinearLayout deviceContainer;
    private List<Switch> deviceSwitches = new ArrayList<>();
    private List<String> deviceTopics = new ArrayList<>();
    private Map<String, Boolean> deviceExists = new HashMap<>(); // 用于记录设备是否已存在

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            mqttBinder = (MqttService.MqttBinder) iBinder;
            mqttBinder.setMqttEventCallback(DevicesDemoActivity.this);
            if (mqttBinder.isConnected()) {
                connectState.setText("已连接");
                subscribeTopics();
            } else {
                connectState.setText("未连接");
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
        }
    };

    void subscribeTopics() {
        try {
            subscribeTopics.put("/test/temp", 1);
            subscribeTopics.put("/test/hum", 2);
            subscribeTopics.put("/test/pm", 3);
            subscribeTopics.put("/test/gas", 4);
            subscribeTopics.put("/test/door", 5);
            for (Map.Entry<String, Integer> entry : subscribeTopics.entrySet()) {
                mqttBinder.subscribe(entry.getKey());
            }
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_devices_demo);

        connectState = findViewById(R.id.dev_connect_state);
        Intent mqttServiceIntent = new Intent(this, MqttService.class);
        bindService(mqttServiceIntent, connection, Context.BIND_AUTO_CREATE);

        temperatureValue = findViewById(R.id.temperature_value);
        humidityValue = findViewById(R.id.humidity_value);
        pmValue = findViewById(R.id.pm_value);
        gasValue = findViewById(R.id.gas_value);
        doorStatus = findViewById(R.id.door_status);

        airConditioningValue = findViewById(R.id.air_conditioning_value);
        parlourLightSwitch = findViewById(R.id.parlour_light_switch);
        parlourLightSwitch.setOnCheckedChangeListener(this);
        curtainSwitch = findViewById(R.id.curtain_switch);
        curtainSwitch.setOnCheckedChangeListener(this);
        fanSocketSwitch = findViewById(R.id.fan_socket_switch);
        fanSocketSwitch.setOnCheckedChangeListener(this);
        airConditioningSwitch = findViewById(R.id.air_conditioning_switch);
        airConditioningSwitch.setOnCheckedChangeListener(this);

        Button addDeviceButton = findViewById(R.id.add_device_button);
        addDeviceButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showAddDeviceDialog();
            }
        });

        Button deleteDeviceButton = findViewById(R.id.delete_device_button);
        deleteDeviceButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showDeleteDeviceDialog();
            }
        });
    }

    private void showAddDeviceDialog() {
        final String[] devices = {"插座", "抽水机"};
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("选择要添加的设备");
        builder.setItems(devices, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                String deviceType = devices[which];
                if (deviceExists.containsKey(deviceType) && deviceExists.get(deviceType)) {
                    Toast.makeText(DevicesDemoActivity.this, deviceType + " 已存在，不能重复添加", Toast.LENGTH_SHORT).show();
                    return;
                }
                String topic;
                if (deviceType.equals("插座")) {
                    topic = "/test/socket1";
                } else {
                    topic = "/test/waterPump";
                }
                addDevice(topic, deviceType);
            }
        });
        builder.show();
    }

    private void addDevice(String topic, String deviceType) {
        try {
            // 找到对应的设备卡片
            View deviceCardView = null;
            Switch deviceSwitch = null;
            if (deviceType.equals("插座")) {
                deviceCardView = findViewById(R.id.socket_device_card);
                deviceSwitch = deviceCardView.findViewById(R.id.socket_switch);
            } else if (deviceType.equals("抽水机")) {
                deviceCardView = findViewById(R.id.water_pump_device_card);
                deviceSwitch = deviceCardView.findViewById(R.id.water_pump_switch);
            }

            if (deviceCardView != null && deviceSwitch != null) {
                // 显示设备卡片
                deviceCardView.setVisibility(View.VISIBLE);

                deviceSwitch.setOnCheckedChangeListener(this);

                // 设置自定义属性存储设备名称
                deviceSwitch.setTag(deviceType);

                // 为 Switch 设置父布局引用
                deviceSwitch.setTag(R.id.device_card_layout, deviceCardView);

                deviceSwitches.add(deviceSwitch);
                deviceTopics.add(topic);
                deviceExists.put(deviceType, true); // 标记设备已存在

                try {
                    mqttBinder.subscribe(topic);
                } catch (MqttException e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            Log.e("DevicesDemoActivity", "Error adding device: " + e.getMessage());
            e.printStackTrace();
        }
    }

    private void showDeleteDeviceDialog() {
        if (deviceTopics.isEmpty()) {
            Toast.makeText(this, "没有可删除的设备", Toast.LENGTH_SHORT).show();
            return;
        }
        final String[] devices = new String[deviceTopics.size()];
        for (int i = 0; i < deviceTopics.size(); i++) {
            // 通过 getTag() 方法获取设备名称
            devices[i] = (String) deviceSwitches.get(i).getTag();
        }
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("选择要删除的设备");
        builder.setItems(devices, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                deleteDevice(which);
            }
        });
        builder.show();
    }

    private void deleteDevice(int index) {
        String topic = deviceTopics.get(index);
        String deviceType = (String) deviceSwitches.get(index).getTag();
        try {
            mqttBinder.unSubscribe(topic);
        } catch (MqttException e) {
            e.printStackTrace();
        }

        // 找到对应的设备卡片
        View deviceCardView = null;
        if (deviceType.equals("插座")) {
            deviceCardView = findViewById(R.id.socket_device_card);
        } else if (deviceType.equals("抽水机")) {
            deviceCardView = findViewById(R.id.water_pump_device_card);
        }

        if (deviceCardView != null) {
            // 隐藏设备卡片
            deviceCardView.setVisibility(View.GONE);
        }

        deviceSwitches.remove(index);
        deviceTopics.remove(index);
        deviceExists.put(deviceType, false); // 标记设备已删除
    }

    @Override
    public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
        switch (compoundButton.getId()) {
            case R.id.parlour_light_switch:
                try {
                    if (compoundButton.isChecked()) {
                        mqttBinder.publishMessage("/test/light1", new Gson().toJson(new BoolMessage(true)));
                    } else {
                        mqttBinder.publishMessage("/test/light1", new Gson().toJson(new BoolMessage(false)));
                    }
                } catch (MqttException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.curtain_switch:
                try {
                    if (compoundButton.isChecked()) {
                        mqttBinder.publishMessage("/test/curtain1", new Gson().toJson(new BoolMessage(true)));
                    } else {
                        mqttBinder.publishMessage("/test/curtain1", new Gson().toJson(new BoolMessage(false)));
                    }
                } catch (MqttException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.fan_socket_switch:
                try {
                    if (compoundButton.isChecked()) {
                        mqttBinder.publishMessage("/test/fan1", new Gson().toJson(new BoolMessage(true)));
                    } else {
                        mqttBinder.publishMessage("/test/fan1", new Gson().toJson(new BoolMessage(false)));
                    }
                } catch (MqttException e) {
                    e.printStackTrace();
                }break;
            case R.id.air_conditioning_switch:
                try {
                    if (compoundButton.isChecked()) {
                        String json = new Gson().toJson(new AirConditioningMessage(true, Float.parseFloat(airConditioningValue.getText().toString())));
                        Log.d(TAG, "json:" + json);
                        mqttBinder.publishMessage("/test/airConditioning", json);
                    } else {
                        String json = new Gson().toJson(new AirConditioningMessage(false, Float.parseFloat(airConditioningValue.getText().toString())));
                        Log.d(TAG, "json:" + json);
                        mqttBinder.publishMessage("/test/airConditioning", json);
                    }
                } catch (MqttException e) {
                    e.printStackTrace();
                }
                break;

            case R.id.socket_switch:
                try {
                    if (compoundButton.isChecked()) {
                        mqttBinder.publishMessage("/test/socket1", new Gson().toJson(new BoolMessage(true)));
                    } else {
                        mqttBinder.publishMessage("/test/socket1", new Gson().toJson(new BoolMessage(false)));
                    }
                } catch (MqttException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.water_pump_switch:
                try {
                    if (compoundButton.isChecked()) {
                        mqttBinder.publishMessage("/test/waterPump", new Gson().toJson(new BoolMessage(true)));
                    } else {
                        mqttBinder.publishMessage("/test/waterPump", new Gson().toJson(new BoolMessage(false)));
                    }
                } catch (MqttException e) {
                    e.printStackTrace();
                }
                break;
        }

    }

    void unSubscribeTopics() {
        try {
            for (Map.Entry<String, Integer> entry : subscribeTopics.entrySet()) {
                mqttBinder.unSubscribe(entry.getKey());
            }
            for (String topic : deviceTopics) {
                mqttBinder.unSubscribe(topic);
            }
            subscribeTopics.clear();
            deviceTopics.clear();
            deviceContainer.removeAllViews();
            deviceSwitches.clear();
            deviceExists.clear(); // 清空设备存在标记
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onConnectSuccess() {
        subscribeTopics();
        connectState.setText("已连接");
    }

    @Override
    public void onConnectError(String error) {
        Log.d(TAG, "onConnectError: " + error);
        connectState.setText("未连接");
        subscribeTopics.clear();
        deviceTopics.clear();
        deviceContainer.removeAllViews();
        deviceSwitches.clear();
        deviceExists.clear(); // 清空设备存在标记
    }

    @Override
    public void onDeliveryComplete() {
        Log.d(TAG, "publish ok");
    }

    @Override
    public void onMqttMessage(String topic, String message) {
        Log.d("onMqttMessage", "topic:" + topic + " message length:" + message.length() + ", message:" + message);
        Gson gson = new Gson();
        switch (subscribeTopics.get(topic)) {
            case 1:
                temperatureValue.setText(String.valueOf(gson.fromJson(message.trim(), FloatMessage.class).value));
                break;
            case 2:
                humidityValue.setText(String.valueOf(gson.fromJson(message.trim(), IntMessage.class).value));
                break;
            case 3:
                pmValue.setText(String.valueOf(gson.fromJson(message.trim(), IntMessage.class).value));
                break;
            case 4:
                int gasValueInt = gson.fromJson(message.trim(), IntMessage.class).value;
                gasValue.setText(String.valueOf(gasValueInt));
                if (gasValueInt > GAS_ALARM_THRESHOLD) {
                    sendGasAlarmNotification();
                }
                break;
            case 5:
                String status = gson.fromJson(message.trim(), BoolMessage.class).value ? "开" : "关";
                doorStatus.setText(status);
                break;
            default:
                int index = deviceTopics.indexOf(topic);
                if (index != -1) {
                    boolean value = false;
                    if (topic.equals("/test/socket1")) {
                        value = gson.fromJson(message.trim(), SocketMessage.class).value;
                    } else if (topic.equals("/test/waterPump")) {
                        value = gson.fromJson(message.trim(), PumpMessage.class).value;
                    }
                    deviceSwitches.get(index).setChecked(value);
                }
        }
    }

    private void sendGasAlarmNotification() {
        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        String channelId = "gas_alarm_channel";

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                    channelId,
                    "Gas Alarm Channel",
                    NotificationManager.IMPORTANCE_HIGH
            );
            notificationManager.createNotificationChannel(channel);
        }

        Notification.Builder builder;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            builder = new Notification.Builder(this, channelId);
        } else {
            builder = new Notification.Builder(this);
        }

        builder.setSmallIcon(android.R.drawable.ic_dialog_alert)
                .setContentTitle("可燃气体浓度过高！")
                .setContentText("当前可燃气体浓度已超过安全阈值，请及时处理！")
                .setPriority(Notification.PRIORITY_HIGH);

        Notification notification = builder.build();
        notificationManager.notify(1, notification);
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        if (mqttBinder.isConnected()) {
            connectState.setText("已连接");
            subscribeTopics();
        } else {
            connectState.setText("未连接");
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        unSubscribeTopics();
    }

    @Override
    protected void onDestroy() {
        unbindService(connection);
        super.onDestroy();
    }
}

